package org.fluidripple.socket.inbound;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufUtil;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelOption;
import lombok.extern.slf4j.Slf4j;
import org.fluidripple.socket.operation.AutomationOperation;
import org.fluidripple.socket.operation.ChannelOperation;
import org.fluidripple.socket.protocol.Protocol;
import org.fluidripple.socket.session.Session;
import org.fluidripple.socket.session.SessionManager;
import org.fluidripple.socket.wrapper.DataWrapper;
import org.springframework.util.StringUtils;

/**
 * 匹配粘包半包处理器
 */
@Slf4j
@ChannelHandler.Sharable
public class DynamicDecoderHandler extends AbstractInboundHandler{

    public static final String name="stick-half";

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg){
        ByteBuf buf= (ByteBuf) msg;
        Channel channel = ctx.channel();
        try {
            String hexDump = ByteBufUtil.hexDump(buf);
            Session session = SessionManager.getSession(ctx);
            log.info("{}--读取到数据包 => {}",session.getDeviceSerializable(),hexDump);
            if (hexDump.equals("f0c103a1a4")){
                session.setCollectData(false);
            }else if (buf.readableBytes()==15){
                session.setCollectData(true);
                String deviceSerializable = session.getDeviceSerializable();
                if (!StringUtils.hasLength(deviceSerializable)){
                    //如果是数据包过来，但是没有设备编号，那就执行如下几步：
                    //1：自动停止采集
                    //2：自动获取设备编号
                    //3：自动开始采集
                    AutomationOperation.addChannel(channel);
                }
            }
            DataWrapper dataWrapper = new DataWrapper(buf,session);
            Protocol protocol = session.getProtocol();
            protocol.decode(dataWrapper);
            buf.skipBytes(buf.readableBytes());
            ctx.fireChannelRead(dataWrapper);
        }catch (Exception exception){
            log.info("系统异常=>",exception);
            ChannelOperation.closeChannel(ctx.channel(),null);
        }
    }
}
